package cn.s1995.sloth.bizs.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.s1995.sloth.bizs.constant.BizCst;
import cn.s1995.sloth.common.core.constant.enums.hint.Hint;
import cn.s1995.sloth.bizs.entity.Order;
import cn.s1995.sloth.bizs.entity.OrderItem;
import cn.s1995.sloth.bizs.entity.ProdEvaluate;
import cn.s1995.sloth.bizs.enums.NotifyTemplateEnum;
import cn.s1995.sloth.bizs.exception.BizException;
import cn.s1995.sloth.bizs.mapper.ProdEvaluateMapper;
import cn.s1995.sloth.bizs.oo.req.OrderEvaluateREQ;
import cn.s1995.sloth.bizs.oo.req.ProdEvaluateREQ;
import cn.s1995.sloth.bizs.oo.vo.ProdEvaluateVO;
import cn.s1995.sloth.bizs.service.MessageService;
import cn.s1995.sloth.bizs.service.OrderItemService;
import cn.s1995.sloth.bizs.service.OrderService;
import cn.s1995.sloth.bizs.service.ProdEvaluateService;
import cn.s1995.sloth.common.core.util.R;
import cn.s1995.sloth.common.security.service.SlothUser;
import cn.s1995.sloth.common.security.util.SecurityUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * 产品评价
 *
 * @author sloth
 * @date 2024-01-02 15:35:58
 */
@Service
public class ProdEvaluateServiceImpl extends ServiceImpl<ProdEvaluateMapper, ProdEvaluate> implements ProdEvaluateService {

	@Resource
	private OrderItemService orderItemService;

	@Resource
	private OrderService orderService;

	@Resource
	private MessageService messageService;


	@Override
	public ProdEvaluateVO getProdData(Long prodId) {
		ProdEvaluateVO vo = new ProdEvaluateVO();
		List<ProdEvaluate> list = this.list(
			Wrappers.lambdaQuery(ProdEvaluate.class)
					.eq(ProdEvaluate::getProdId, prodId)
					.eq(ProdEvaluate::getState, BizCst.CommonAuditState.approve)
		);
		Map<Integer, Long> scoreGroup = null;
		if(ObjectUtil.isNotEmpty(list)) {
			double avgScore = list.stream().mapToInt(e -> e.getScore()).average().getAsDouble();
			vo.setAvg(Math.round(avgScore * 10) / 10D);
			vo.setCount(list.size());
			scoreGroup = list.stream()
				.collect(Collectors.groupingBy(ProdEvaluate::getScore, Collectors.counting()));
		}else {
			vo.setAvg(0D);
			vo.setCount(0);
			scoreGroup = new HashMap<Integer, Long>();
		}
		for(int i = 5; i > 0; i--) {
			scoreGroup.putIfAbsent(i, 0L);
		}
		vo.setGroup(scoreGroup);
		return vo;
	}

	@Override
	public R saveProdEvaluate(ProdEvaluateREQ req) {
		if(ObjectUtil.isNull(req.getScore())){
			req.setScore(5);
		}
		SlothUser user = SecurityUtils.getUser();
		Long uid = user.getId();
		ProdEvaluate old = this.getOne(
			Wrappers.lambdaQuery(ProdEvaluate.class)
					.eq(ObjectUtil.isNotNull(req.getOrderItemId()),ProdEvaluate::getOrderItemId, req.getOrderItemId())
//					.eq(ObjectUtil.isNotNull(req.getId()),ProdEvaluate::getId, req.getId())
		);
		if(ObjectUtil.isNotNull(old)) {
			//修改
			if(!uid.equals(old.getUid()))
				throw new BizException(Hint.APP_YOU_HAVE_NO_PERMISSION_TO_GET_THE_ORDER_INFORMATION);
			this.update(
					Wrappers.lambdaUpdate(ProdEvaluate.class)
							.eq(ProdEvaluate::getId, old.getId())
							.set(ObjectUtil.isNotNull(req.getContent()),ProdEvaluate::getContent, req.getContent())
							.set(ObjectUtil.isNotNull(req.getPics()),ProdEvaluate::getPics, req.getPics())
							.set(ObjectUtil.isNotNull(req.getVideo()),ProdEvaluate::getVideo, req.getVideo())
							.set(ObjectUtil.isNotNull(req.getScore()),ProdEvaluate::getScore, req.getScore())
			);
		}else {
			if(ObjectUtil.isNotNull(req.getOrderItemId())) {
				OrderItem orderItem = orderItemService.getById(req.getOrderItemId());
				if(ObjectUtil.isNotNull(orderItem)) {
					if(!uid.equals(orderItem.getUid()))
						throw new BizException(Hint.APP_YOU_HAVE_NO_PERMISSION_TO_GET_THE_ORDER_INFORMATION);
					//新增
					this.save(
							ProdEvaluate.builder()
										.state(BizCst.CommonAuditState.approve)
										.prodId(orderItem.getProdId())
										.uid(uid)
										.userNickname(user.getNickname())
										.userAvatar(user.getAvatar())
										.orderId(orderItem.getOrderId())
										.orderItemId(req.getOrderItemId())
										.content(req.getContent())
										.pics(req.getPics())
										.video(req.getVideo())
										.score(req.getScore())
										.isAnonymous(req.isAnonymous())
										.build()
					);
				}
			}
		}
		return R.ok();
	}


	@Override
	@Transactional
	public R addBatch(@Valid OrderEvaluateREQ req) {
		Long uid = SecurityUtils.getUser().getId();
		Order order = orderService.getById(req.getOrderId());
		if(ObjectUtil.isNull(order) || !order.getState().equals(BizCst.Order.State.confirm) || !order.getUid().equals(uid)) {
			throw new BizException(Hint.FORBIDDEN);
		}
		for (ProdEvaluateREQ evaluation : req.getEvaluations()) {
			this.saveProdEvaluate(evaluation);
		}
		order.setState(BizCst.Order.State.completed);
		order.setCompleteTime(LocalDateTime.now());
		orderService.updateById(order);
		// 发送消息
        messageService.sendMsg(
    			NotifyTemplateEnum.order_completed.getId(),
    			0L,
    			uid,
    			BizCst.Message.Type.order,
    			BizCst.Message.BindType.order,
    			order.getId()
    	);
		return R.ok();
	}
}
